package com.example.naodian.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.naodian.context.BaseContext;
import com.example.naodian.domain.dto.*;
import com.example.naodian.domain.po.User;
import com.example.naodian.domain.vo.UserVO;
import com.example.naodian.exception.BaseException;
import com.example.naodian.exception.LoginFailedException;
import com.example.naodian.mapper.UserMapper;
import com.example.naodian.result.PageResult;
import com.example.naodian.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author icewx
 * @since 2025-04-14
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    /**
     * 用户登录接口
     * @param loginDto
     * @return
     */
    @Override
    public User login(LoginDto loginDto) {
        String username = loginDto.getUsername();
        String password = loginDto.getPassword();
        //1.根据用户名查询用户信息
        User user = lambdaQuery().eq(User::getUsername, username).one();

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (user == null){
            throw new LoginFailedException("用户不存在!");
        }
        //加密过的密码进行校验
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(user.getPassword())){
            throw new LoginFailedException("密码不正确!");
        }
        //对用户状态进行校验
        if (user.getStatus() == 1){
            throw new LoginFailedException("用户状态异常!");
        }
        return user;
    }

    /**
     * 注册驾驶员账号(用户注册)
     * @param resUserDto
     * @return
     */
    @Override
    public void reg(ResUserDto resUserDto) {
        //1.判断新注册的用户是否存在
        User dbUser = lambdaQuery().eq(User::getUsername, resUserDto.getUsername()).one();
        if (dbUser != null){
            //也可以自定义异常类见到见名知意
            throw new BaseException("该用户已存在!");
        }
        //2.判断两个密码是否相同
        if (!resUserDto.getPassword().equals(resUserDto.getConfirmPassword())){
            throw new BaseException("两次密码必须相同!");
        }
        //3.如果通过校验，则成功注册驾驶员账号,账号默认启用，角色为驾驶员
       save( User.builder()
               .username(resUserDto.getUsername())
               .password(DigestUtils.md5DigestAsHex(resUserDto.getPassword().getBytes())) //加密密码
               .role(2)
               .status(0)
               .build());
    }

    /**
     * 添加驾驶员(管理员添加)
     * @param userDto
     * @return
     */
    @Override
    public void add(UserDto userDto) {
        //管理员添加用户密码默认为 "123456"
        String password = "123456";
        User user = BeanUtil.copyProperties(userDto, User.class);
        user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        save(user);

    }

    /**
     * 根据id查询驾驶员信息
     * @param id
     * @return
     */
    @Override
    public UserVO getUserById(Long id) {
        User user = lambdaQuery().eq(User::getId, id).one();
        if (user == null){
            throw new BaseException("用户不存在!");
        }
        return BeanUtil.copyProperties(user, UserVO.class);
    }

    /**
     * 修改驾驶员信息
     * @param editUserDto
     * @return
     */
    @Override
    public void editUsernameAndPassWord(EditUserDto editUserDto) {
        String oldPassWord = editUserDto.getOldPassWord();
        String newPassWord = editUserDto.getNewPassWord();

        //1.将传过来的新旧密码进行加密比较
        oldPassWord = DigestUtils.md5DigestAsHex(oldPassWord.getBytes());
        newPassWord = DigestUtils.md5DigestAsHex(newPassWord.getBytes());

        //2.根据登录人用户名查询登录人信息
        User dbUser = lambdaQuery().eq(User::getId, BaseContext.getCurrentId()).one();
        if (dbUser == null){
            throw new BaseException("用户不存在");
        }

        //3.旧密码要正确，新密码不能与旧密码相同
        if (!dbUser.getPassword().equals(oldPassWord) || dbUser.getPassword().equals(newPassWord)){
            throw new BaseException("旧密码不正确，或新密码与旧密码相同");
        }

        //4.修改信息
        lambdaUpdate().set(User::getUsername,editUserDto.getUsername())
                .set(User::getPassword,newPassWord)
                .set(User::getUpdateTime,LocalDateTime.now())
                .eq(User::getId,dbUser.getId())
                .update();
    }

    /**
     * 根据用户id修改用户的状态
     * @param status
     * @param id
     * @return
     */
    @Override
    public void editRoleAndStatus(Integer status,Long id) {
        lambdaUpdate()
                .set(status != null,User::getStatus,status)
                .set(User::getUpdateTime,LocalDateTime.now())
                .eq(User::getId,id)
                .update();
    }

    /**
     * 根据用户id查询用户预警值
     * @param id
     * @return
     */
    @Override
    public Double getWarningValueByUserId(Long id) {
        User user = lambdaQuery()
                .eq(User::getId, id)
                .one();
        return user.getWarningValue();
    }


    /**
     * 用户分页查询
     * @param userPageQueryDto
     * @return
     */
    @Override
    public PageResult pageQuery(UserPageQueryDto userPageQueryDto) {
        //构建分页条件
        Page<User> page = userPageQueryDto.toMpPageDefaultSortByCreateTimeDesc();

        //分页查询
        Page<User> userPage = lambdaQuery()
                .like(userPageQueryDto.getName() != null,User::getUsername,userPageQueryDto.getName())
                .page(page);

        // 3.调用插件获得数据
        //获得总的记录数
        long total = userPage.getRecords().size();
        //获得总的页数
//        long pages = userPage.getPages();
        //获得当前页数据集合
        List<User> userList = userPage.getRecords();

        List<UserVO> records = BeanUtil.copyToList(userList, UserVO.class);

        // 4.返回封装好的分页结果
        return new PageResult(total,records);

    }
}
